package cn.org.xiaosheng.common.config;


import cn.org.xiaosheng.service.CacheService;
import cn.org.xiaosheng.service.impl.CacheServiceImpl;
import com.google.common.cache.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Configuration
public class GuavaCacheConfig {

   public static CacheService cacheService() {
       return new CacheServiceImpl();
   }

    /**
     * 移除监听器
     */
    static RemovalListener<String, String> MY_LISTENER_01 = removal -> {
        System.out.println(removal + "被移除了");
    };
    /**
     * 异步移除监听器  需要添加异步执行的线程池
     */
    static RemovalListener<String, String> MY_LISTENER_02=RemovalListeners.asynchronous(removal -> {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(removal + "被异步移除了");
    }, Executors.newSingleThreadExecutor());

    /**
     * 在这个例子中，我们首先使用CacheBuilder创建了一个LoadingCache，并设置了一些参数，如最大容量、写后过期时间、开启统计信息等。然后我们定义了CacheLoader来加载缓存数据。
     */
    public static final LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
            .maximumSize(100) // 设置缓存的最大容量
            .expireAfterWrite(10, TimeUnit.MINUTES) // 设置缓存在写入10分钟后失效
            .recordStats() // 开启缓存统计
            .removalListener(MY_LISTENER_01) // 添加元素移除监听器
//            .refreshAfterWrite(3,TimeUnit.SECONDS)  //  3秒内阻塞会返回旧数据
//            .concurrencyLevel(Runtime.getRuntime().availableProcessors())  // 同时支持CPU核数线程写缓存
//            .expireAfterAccess(3, TimeUnit.SECONDS) // 隔多3分钟后没有被访问过的key被删除
//            .expireAfterWrite(3, TimeUnit.SECONDS)  // 写入3分钟后过期，等同于expire ttl 缓存中对象的生命周期就是3秒
//            .maximumSize(3)  // 缓存最大元素数
//            .weakValues()  // 值的弱引用
            .build(new CacheLoader<String, String>() { // 设置缓存的加载方式
                @Override
                public String load(String key) {
                    return cacheService().getDataFromDatabase(key);
                }

                @Override
                public Map<String, String> loadAll(Iterable<? extends String> keys) throws Exception {
                    return super.loadAll(keys);
                }
            });

    public static final Cache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(100) // 设置缓存的最大容量
            .expireAfterWrite(10, TimeUnit.MINUTES) // 设置缓存在写入10分钟后失效
            .recordStats() // 开启缓存统计
            .removalListener(MY_LISTENER_02)
            .build();

    @Bean
    public LoadingCache<String, String> guavaLoadingCache() {
        return loadingCache;
    }

    @Bean
    public Cache guavaCache() {
        return cache;
    }




}
